package com.jiangli.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jiangli.context.BaseContext;
import com.jiangli.dto.*;
import com.jiangli.entity.Dish;
import com.jiangli.entity.DishFlavor;
import com.jiangli.entity.Ingredient;
import com.jiangli.entity.Merchant;
import com.jiangli.mapper.DishFlavorMapper;
import com.jiangli.mapper.DishMapper;
import com.jiangli.mapper.DishRatingMapper;
import com.jiangli.mapper.IngredientMapper;
import com.jiangli.result.PageResult;
import com.jiangli.service.AdminDishService;
import com.jiangli.service.Search.DishIndexService;
import com.jiangli.vo.DishBriefVO;
import com.jiangli.vo.DishRatingAdminVO;
import com.jiangli.vo.DishVO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sky.entity.DishIngredient;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@Service
@Slf4j
public class AdminDishServiceImpl implements AdminDishService {
    private final DishMapper dishMapper;
    private final DishIndexService dishIndexService;
    private final StringRedisTemplate stringRedisTemplate;
    private final DishServiceImpl dishServiceImpl;
    private final MerchantServiceImpl merchantServiceImpl;
    private final IngredientMapper ingredientMapper;
    private static final String INGREDIENT_DISH_ID_PREFIX = "ingredient:dishIdsConnection:";
    private final DishRatingMapper dishRatingMapper;
    private final DishFlavorMapper dishFlavorMapper;
    private final ObjectMapper objectMapper;
    @Autowired
    public AdminDishServiceImpl(DishMapper dishMapper,
                                DishIndexService dishIndexService,
                                StringRedisTemplate stringRedisTemplate,
                                DishServiceImpl dishServiceImpl,
                                MerchantServiceImpl merchantServiceImpl,
                                IngredientMapper ingredientMapper,
                                DishRatingMapper dishRatingMapper,
                                DishFlavorMapper dishFlavorMapper,
                                ObjectMapper objectMapper) {
        this.dishMapper = dishMapper;
        this.dishIndexService = dishIndexService;
        this.stringRedisTemplate = stringRedisTemplate;
        this.dishServiceImpl = dishServiceImpl;
        this.merchantServiceImpl = merchantServiceImpl;
        this.ingredientMapper = ingredientMapper;
        this.dishRatingMapper = dishRatingMapper;
        this.dishFlavorMapper = dishFlavorMapper;
        this.objectMapper = objectMapper;
    }

    private static final String CATEGORY_IDS_KEY_PREFIX = "dish:category:ids:";//菜品分类ids
    private static final String DISH_METADATA_KEY = "dish:all:metadata";//菜品元数据
    private static final String TOTAL_COUNT_KEY = "dish:total:count";//菜品总数
    private static final String DISH_DETAIL_PREFIX = "dish:detail:";//菜品详情
    private static final String DISH_INGREDIENT_PREFIX = "dish:ingredientIds:";//菜品有关的材料
    private static final String MERCHANT_DISH_IDS ="merchant:dish:ids:" ;
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("新增菜品")
    public void addDish(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        if(BaseContext.getCurrentId()!=null)
        {
        dish.setCreateUser(Integer.valueOf(BaseContext.getCurrentId().toString()));
        }else {
            dish.setCreateUser(1);
        }
        log.info("添加菜品");
        dishMapper.addDish(dish);
        log.info("添加后");
        //添加菜品材料
        if(dishDTO.getIngredientIds()!=null && !dishDTO.getIngredientIds().isEmpty())
        {DishIngredientDTO ingredientDTO = new DishIngredientDTO();
        ingredientDTO.setDishId(dish.getId());
        ingredientDTO.setIngredientIds(dishDTO.getIngredientIds());
        ingredientDTO.setDishName(dish.getDishName());
        addIngredient(ingredientDTO);}
        //添加菜品口味 addFlavor(DishFlavorDTO dishFlavorDTO)
        if(dishDTO.getFlavors()!=null && !dishDTO.getFlavors().isEmpty())
        {DishFlavorDTO dishFlavorDTO = new DishFlavorDTO();
        dishFlavorDTO.setDishId(dish.getId());
        dishFlavorDTO.setName(dishDTO.getFlavors());
        addFlavor(dishFlavorDTO);}
        //构建索引
        dishIndexService.buildDishIndex(dish);
        //删除有关的菜品分类ids缓存
        deleteDishCategoryId(dish);
        //删除菜品元数据
        stringRedisTemplate.delete(DISH_METADATA_KEY);
        //删除菜品总数
        stringRedisTemplate.delete(TOTAL_COUNT_KEY);
        //删除商家菜品id列表
        stringRedisTemplate.delete(MERCHANT_DISH_IDS+dish.getMerchantId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDish(Long id) {
        ingredientMapper.deleteConectionByDishId(id);
        dishFlavorMapper.deletByDishId(id);
        Dish dish = dishMapper.getByDishId(id);
        dishMapper.deleteDish(id);
        if(dish != null)
        {//删除索引
        dishIndexService.deleteDishIndex(id);
        //删除有关的菜品分类ids缓存
        deleteDishCategoryId(dish);
        //删除菜品元数据
        stringRedisTemplate.delete(DISH_METADATA_KEY);
        //删除菜品总数
        stringRedisTemplate.delete(TOTAL_COUNT_KEY);
        //删除缓存中菜品详情
        stringRedisTemplate.delete(DISH_DETAIL_PREFIX + id);
        stringRedisTemplate.delete(MERCHANT_DISH_IDS+dish.getMerchantId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDish(DishUpdateDTO dishUpdateDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishUpdateDTO, dish);
        Dish dishLast = dishMapper.getByDishId(dish.getId());
        dish.setCreateUser(Integer.valueOf(BaseContext.getCurrentId().toString()));
        dishMapper.update(dish);
        //删除有关的菜品分类ids缓存
        if(dishLast != null && dishLast.getDishCategoryId() != null)
        {
            deleteDishCategoryId(dishLast);
        }
        if(dish.getDishCategoryId()!= null)
        {
            deleteDishCategoryId(dish);
        }
        //删除索引
        dishIndexService.deleteDishIndex(dish.getId());
        //构建索引
        dishIndexService.buildDishIndex(dish);
        //删除缓存中菜品详情
        stringRedisTemplate.delete(DISH_DETAIL_PREFIX + dish.getId());
        //删除菜品元数据
        stringRedisTemplate.delete(DISH_METADATA_KEY);
        stringRedisTemplate.delete(MERCHANT_DISH_IDS+dish.getMerchantId());

    }

    @Override
    public PageResult getDishByPage(DishPageQueryDTO dishPageQueryDTO) {
        List<Dish> dishList = dishServiceImpl.getAllDishesWithCache();
        List<Long> dishIds = dishFilter(dishList,dishPageQueryDTO);
        PageResult pageResult = new PageResult();
        pageResult.setTotal(dishIds.size());
        pageResult.setRecords(getDishesByPage(dishIds,dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize()));
        return pageResult;
    }

    @Override
    public DishVO getDishDetial(Long id) {
        return dishServiceImpl.getDishDetailById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addIngredient(DishIngredientDTO dishIngredientDTO) {
        Long dishId = dishIngredientDTO.getDishId();
        ingredientMapper.deleteConectionByDishId(dishId);
        String dishName = dishIngredientDTO.getDishName();
        List<Long> ingredientIds = dishIngredientDTO.getIngredientIds();
        List<Ingredient> ingredientList = dishServiceImpl.getDetailIngredient(ingredientIds);
        List<DishIngredient> dishIngredientList = new ArrayList<>();
        for (int i = 0; i < ingredientList.size(); i++) {
            DishIngredient dishIngredient = new DishIngredient();
            dishIngredient.setDishId(Math.toIntExact(dishId));
            dishIngredient.setDishName(dishName);
            dishIngredient.setIngredientId(Math.toIntExact(ingredientIds.get(i)));
            dishIngredient.setIngredientName(ingredientList.get(i).getName());
            dishIngredientList.add(dishIngredient);
        }
        //删除材料下有关的菜品ids
        for(Long ingredientId : ingredientIds)
        {
            String key =INGREDIENT_DISH_ID_PREFIX + ingredientId;
            if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(key)))
            {
                stringRedisTemplate.delete(key);
            }
        }
        stringRedisTemplate.delete(DISH_INGREDIENT_PREFIX + dishId);
        if(!dishIngredientList.isEmpty())
        {ingredientMapper.addDishIngredient(dishIngredientList);}

    }

    @Override
    public PageResult getUserRating(Long id,Long page,Long pageSize) {
//        PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
//        Page<DishVO> page = dishMapper.pageQuery(dishPageQueryDTO);
//        return new PageResult(page.getTotal(), page.getResult());
        PageHelper.startPage(Math.toIntExact(page), Math.toIntExact(pageSize));
        Page<DishRatingAdminVO> pageResult = dishRatingMapper.getDishRatingByDishId(id);
        PageResult pageResult2 = new PageResult();
        pageResult2.setTotal(pageResult.getTotal());
        pageResult2.setRecords(pageResult.getResult());
        return pageResult2;
    }

    @Override
    public void addFlavor(DishFlavorDTO dishFlavorDTO) {
        DishFlavor dishFlavor = dishFlavorMapper.getFlavorByDishId(dishFlavorDTO.getDishId());
        if(dishFlavor!= null){

            if(dishFlavorDTO.getName()!=null)
            {
                String name;
                try {
                    name = objectMapper.writeValueAsString(dishFlavorDTO.getName()) ;
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                dishFlavor.setFlavorName(name);
            }else{
                dishFlavor.setFlavorName("");
            }
            dishFlavorMapper.update(dishFlavor);
        }else
        {
            dishFlavor = new DishFlavor();
            dishFlavor.setDishId(dishFlavorDTO.getDishId());
            if(dishFlavorDTO.getName()!=null)
            {
                String name;
                try {
                    name = objectMapper.writeValueAsString(dishFlavorDTO.getName()) ;
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                dishFlavor.setFlavorName(name);

            }
            dishFlavorMapper.insertBatch(Collections.singletonList(dishFlavor));
        }
    }

    /**
     * 获取材料列表
     * @param ingredientName 材料名字
     * @return list集合
     */
    @Override
    public List<Ingredient> getIngredients(String ingredientName) {
        return ingredientMapper.getIngredientsByName(ingredientName);
    }

    /*
      过滤不符合条件的菜品
      @param dishList 菜品
     * @param dishPageQueryDTO 分页查询条件
     * @return 返回ids
     */
    private List<Long> dishFilter(List<Dish> dishList, DishPageQueryDTO dishPageQueryDTO) {
        String dishName = dishPageQueryDTO.getName();
        Long merchantId = dishPageQueryDTO.getMerchant();
        Long categoryId = dishPageQueryDTO.getCategoryId();
        return dishList.stream()
                .filter(dish -> {


                    // 菜品名称模糊匹配（包含关键字即可）
                    if (dishName != null) {
                        // 处理菜品名称可能为null的情况，避免空指针
                        if (dish.getDishName() == null || !dish.getDishName().contains(dishName)) {
                            return false;
                        }
                    }

                    // 商户ID精确匹配
                    if (merchantId != null) {
                        if (dish.getMerchantId()!=null && !merchantId.equals(Long.valueOf(dish.getMerchantId()))) {
                            return false;
                        }
                    }

                    // 分类ID匹配逻辑保持不变
                    if (categoryId != null) {
                        boolean pass = false;
                        int number = dish.getDishCategoryId();
                        while (number > 0) {
                            int dishCategory = number % 10;
                            if (dishCategory == categoryId) {
                                pass = true;
                                break;
                            }
                            number /= 10;
                        }
                        return pass;
                    }

                    return true;
                })
                .map(Dish::getId).sorted(Comparator.reverseOrder())
                .toList();
    }

    /**
     * 删除有关菜品的分类的ids缓存
     * @param dish 菜品
     */
    private void deleteDishCategoryId(Dish dish) {
        int number = dish.getDishCategoryId();
        log.info("number:{}",number);
        while(number > 0) {
            int dishCategory = number % 10;
            String categoryKey = CATEGORY_IDS_KEY_PREFIX + dishCategory;
            if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(CATEGORY_IDS_KEY_PREFIX + dishCategory))) {
                stringRedisTemplate.delete(categoryKey);
            }
            number /= 10;
        }
    }

    /**
     * 获取菜品分页
     * @param allIds 需要的ids
     * @param page 需要第几页
     * @param size 页数大小
     */
    private List<DishBriefVO> getDishesByPage(List<Long> allIds, int page, int size) {
        // 计算分页范围
        int start = (page - 1) * size;
        if (start < 0) start = 0;
        int end = Math.min(start + size, allIds.size());

        // 如果没有数据，返回空列表
        if (start >= end) {
            return Collections.emptyList();
        }

        // 获取当前页的ID列表
        List<Long> pageIds = allIds.subList(start, end);
        List<Dish> dishList = dishServiceImpl.getDishesFromCacheOrDB(pageIds);
        List<DishBriefVO> dishList2 = new ArrayList<>();
        for (Dish value : dishList) {
            DishBriefVO dishVO = new DishBriefVO();
            List<Long> merchantIds = new ArrayList<>();
            merchantIds.add((Long.valueOf(value.getMerchantId())));
            List<Merchant> merchant = merchantServiceImpl.getCurrentMerchant(merchantIds);
            log.info("商家应该有一个{}", merchant.size());
            merchant.add(new Merchant());
            BeanUtils.copyProperties(value, dishVO);
            log.info("商家{}", merchant.get(0));
            dishVO.setMerchant(merchant.get(0).getMerchantName());
            dishVO.setLocation(merchant.get(0).getLocation());
            dishList2.add(dishVO);
        }
        // 查询菜品详情
        return dishList2;
    }

}
